/*
 * ﻿Copyright (C) 2012 NewMain Softech
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.newmainsoftech.ant.types;

import java.lang.reflect.Field;

import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.CommandlineJava;

/**
 * Wrapper class of {@link CommandlineJava} for {@link CommandlineJavaExtAspect} aspect to inject 
 * {@link CommandlineExt} object to <code>javaCommand</code> member field and <code>vmCommand</code> 
 * member field of <code>CommandlineJava</code> object. 
 * 
 * @author <a href="mailto:artymt@gmail.com">Arata Y.</a>
 */
public class CommandlineJavaExt extends CommandlineJava {
	public CommandlineJavaExt() {
		super();
	}
	
	static Field getCommandlineJavaField( String fieldName) {
		try {
			Field field = CommandlineJava.class.getDeclaredField( fieldName);
				field.setAccessible( true);
			return field;
		}
		catch( Exception exception) {
			if ( exception instanceof RuntimeException) throw (RuntimeException)exception;
			throw new RuntimeException(
					String.format(
							"Could not find %1$s member field in %2$s class. %2$s class needs to be " 
							+ "updated if %3$s class get changed since %2$s class has been developed.",
							fieldName,
							CommandlineJavaExt.class.getName(),
							CommandlineJava.class.getName()
							),
					exception 
					);
		}
	}
	
	// Regarding javaCommand ----------------------------------------------------------------------
	static final Field javaCommandField = getCommandlineJavaField( "javaCommand");
		static {
			if ( !Commandline.class.equals( javaCommandField.getType())) {
				throw new RuntimeException(
						String.format(
								"Expected that type of %1$s member field of %2$s class was %3$s but " 
								+ "detected actually %4$s. There got to be change on %2$s class after %5$s " 
								+ "development and %5$s and other classes in %6$s may need to be updated.",
								javaCommandField.getName(),
								CommandlineJava.class.getName(),
								Commandline.class.getName(),
								javaCommandField.getType().getName(),
								CommandlineJavaExt.class.getName(),
								CommandlineJavaExt.class.getPackage().getName()
								)
						);
			}
		};
		static Field getJavaCommandField() {
			return javaCommandField;
		}
	CommandlineExt getJavaCommandMemberFieldObj() {
		try {
			return (CommandlineExt)(CommandlineJavaExt.getJavaCommandField().get( this));
		}
		catch( Exception exception) {
			if ( exception instanceof RuntimeException) throw (RuntimeException)exception;
			throw new RuntimeException(
					String.format(
							"Failure in accessing %1$s memeber field of %2$s.",
							CommandlineJavaExt.getJavaCommandField().getName(),
							this.toString()
							),
					exception
					);
		}
	}
	
	public ArgumentExtContract createArgext() {
		return (ArgumentExt)(getJavaCommandMemberFieldObj().createArgument());
	}
	// --------------------------------------------------------------------------------------------
	
	// Regarding vmCommand ------------------------------------------------------------------------
	static final Field vmCommandField = getCommandlineJavaField( "vmCommand");
		static {
			if ( !Commandline.class.equals( vmCommandField.getType())) {
				throw new RuntimeException(
						String.format(
								"Expected that type of %1$s member field of %2$s class was %3$s but " 
								+ "detected actually %4$s. There got to be change on %2$s class after %5$s " 
								+ "development and %5$s and other classes in %6$s may need to be updated.",
								vmCommandField.getName(),
								CommandlineJava.class.getName(),
								Commandline.class.getName(),
								vmCommandField.getType().getName(),
								CommandlineJavaExt.class.getName(),
								CommandlineJavaExt.class.getPackage().getName()
								)
						);
			}
		};
		static Field getVmCommandField() {
			return vmCommandField;
		}
	CommandlineExt getVmCommandMemberFieldObj() {
		try {
			return (CommandlineExt)(CommandlineJavaExt.getVmCommandField().get( this));
		}
		catch( Exception exception) {
			if ( exception instanceof RuntimeException) throw (RuntimeException)exception;
			throw new RuntimeException(
					String.format(
							"Failure in accessing %1$s memeber field of %2$s.",
							CommandlineJavaExt.getVmCommandField().getName(),
							this.toString()
							),
					exception
					);
		}
	}
	
	public ArgumentExtContract createVmargext() {
		return (ArgumentExt)(getVmCommandMemberFieldObj().createArgument());
	}
	// --------------------------------------------------------------------------------------------
}
